home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MacHack 1997
/
MacHack 1997.toast
/
Hacks
/
Hacks ’93
/
The Regulator 1.4
/
PB.c
< prev
next >
Wrap
Text File
|
1993-06-04
|
7KB
|
303 lines
/*
** PB.c
**
** PowerBook specific routines for setting & getting various sleep and rest values.
** of course, any of these can change at any time, and they aren't official
** nor from Apple. I figured these out by disassembling code. This stuff WILL
** change in the future. Don't base any products on this, or you'll be very
** sorry (and DTS will laugh in your face…) Don't ask Apple for help on this
** stuff… they have no further information they are willing to disclose.
*/
#include "XPRAM.h"
#include <Power.h>
#include <GestaltEqu.h>
#include <SegLoad.h>
#include <Folders.h>
#include <Files.h>
#include <Memory.h>
#include <Resources.h>
#ifdef THINK_C
/* These are defined in MPW C 3.2.3, but not in Think C 5.0.2 */
#define gestaltPowerBook100 24 /* not defined in GestaltEqu.h */
#define gestaltPowerBook140 25 /* not defined in GestaltEqu.h */
#define gestaltPowerBook145 54
#define gestaltPowerBook170 21 /* not defined in GestaltEqu.h */
#define gestaltDuo230 29
#define gestaltDuo210 32
#define gestaltPowerBook180 33
#define gestaltPowerBook160 34
#define gestaltPowerBook165c 50
#endif
#define kUnitsOfSleep (60/15) /* empirical from source */
#define kMaxSysSleep 15*kUnitsOfSleep
#define kMaxHDSleep 15*kUnitsOfSleep
#define kByteSize 1
/* globals */
Boolean gOnBattery; /* charger connection determines this */
short gFlagsLocation;
Byte gSysSleep;
Byte gHDSleep;
/* procedures declared in this module */
OSErr CheckForMains();
void SetPMgrDirty();
Boolean ToggleFlag(short, Byte, Boolean);
Boolean SetDontRest();
Boolean SetRest();
// Byte GetUserSysSleep();
// Byte GetUserHDSleep();
void SetSysSleep();
void SetHDSleep();
void InitPortableStuff();
void InitPrefs();
/* CheckForMains
*
* This is the routine we invoke when called periodically.
* Check for battery status. if we've recently been plugged in, modify
* the idle state.
*/
OSErr
CheckForMains()
{
Byte status;
Byte power;
Boolean currentlyConnected;
OSErr err;
err = BatteryStatus(&status, &power);
if ( noErr == err )
{
currentlyConnected = status & chargerConnMask;
if (currentlyConnected != gOnBattery)
{
if (!currentlyConnected) { /* we just got disconnected from the mains */
SetRest();
SetSysSleep(gSysSleep);
SetHDSleep(gHDSleep);
}
else { /* we just connected to the mains */
SetDontRest();
//gSysSleep = GetUserSysSleep();
//gHDSleep = GetUserHDSleep();
SetSysSleep(kMaxSysSleep);
SetHDSleep(kMaxHDSleep);
}
gOnBattery = currentlyConnected;
}
}
return err;
}
/* Set the Power Manager's dirty byte whenever anything changes */
void SetPMgrDirty()
{
PMgrLocal(TOdirtyFlag) = 0xff; /* set the byte */
}
/*
* Toggle a flag in prFlags
* Return the new state of the flag
*/
Boolean ToggleFlag(short flagPramAddr,Byte bit, Boolean newState)
{
Byte scratch;
ReadPRAM(flagPramAddr, kByteSize, (char *)&scratch); /* Read the current state */
if (newState)
scratch |= bit;
else
scratch &= ~bit;
SetPRAM(flagPramAddr, kByteSize, (char *)&scratch); /* Put it back */
SetPMgrDirty(); /* Tell PMgr to notice the change */
return newState; /* return the new state */
}
/*
* Set the "Don't Rest while plugged in" flag in PRAM
*/
Boolean SetDontRest()
{
Boolean result;
result = ToggleFlag(gFlagsLocation,kPowerSave, true);
return result;
}
/*
* Set the "Rest while plugged in" flag in PRAM
*/
Boolean SetRest()
{
Boolean result;
result = ToggleFlag(gFlagsLocation,kPowerSave, false);
return result;
}
#if 0
/*
** GetUserSysSleep
** read the PRAM and return what the user set gSysSleep to be
*/
Byte GetUserSysSleep()
{
Byte scratch;
ReadPRAM(PRAM_BASE+prSysSleep_Offset, kByteSize, (char *)&scratch);
return scratch;
}
/*
** GetUserHDSleep
** read the PRAM and return what the user set gHDSleep to be
*/
Byte GetUserHDSleep()
{
Byte scratch;
ReadPRAM(PRAM_BASE+prHDSleep_Offset, kByteSize, (char *)&scratch);
return scratch;
}
#endif
/*
** SetSysSleep
** read the PRAM and return what the user set gSysSleep to be
*/
void SetSysSleep(newValue)
Byte newValue;
{
SetPRAM(PRAM_BASE+prSysSleep_Offset, kByteSize, (char *)&newValue);
SetPMgrDirty(); /* Tell PMgr to notice the change */
}
/*
** SetHDSleep
** read the PRAM and return what the user set gHDSleep to be
*/
void SetHDSleep(newValue)
Byte newValue;
{
SetPRAM(PRAM_BASE+prHDSleep_Offset, kByteSize, (char *)&newValue);
SetPMgrDirty(); /* Tell PMgr to notice the change */
}
/*
** InitPortableStuff
** set globals so they work with the Portable model we have.
** We only work with the Portable, PowerBook100, PowerBook140, and PowerBook170
** (Heck, who knows what the future brings?)
*/
void InitPortableStuff()
{
Byte status;
Byte power;
OSErr err;
long gestaltData;
Boolean knownComputer;
long globals;
long powerManagerBase;
Gestalt(gestaltPowerMgrAttr, &gestaltData);
if (!(gestaltData & (1 << gestaltPMgrExists)) ) {
ExitToShell();
}
Gestalt(gestaltMachineType, &gestaltData);
knownComputer = (gestaltData == gestaltPortable)
|| (gestaltData == gestaltPowerBook100)
|| (gestaltData == gestaltPowerBook140)
|| (gestaltData == gestaltPowerBook170);
if (!knownComputer)
ExitToShell();
err = BatteryStatus(&status, &power);
gOnBattery = ~(status & chargerConnMask); /* this ensures we'll do something */
/* 1st time around */
#if 0
gSysSleep = GetUserSysSleep();
gHDSleep = GetUserHDSleep();
#endif
Gestalt(gestaltMachineType, &gestaltData);
switch (gestaltData) {
case gestaltPortable:
case gestaltPowerBook100:
gFlagsLocation = PRAM_BASE+prFlags_Offset_Portable;
break;
case gestaltPowerBook140:
case gestaltPowerBook145:
case gestaltPowerBook170:
gFlagsLocation = PRAM_BASE+prFlags_Offset;
break;
case gestaltDuo210:
case gestaltDuo230:
case gestaltPowerBook180:
case gestaltPowerBook160:
case gestaltPowerBook165c:
globals = * ((long *)(0x00000D18));
powerManagerBase = *((char *)globals + 0x55);
gFlagsLocation = powerManagerBase+prFlags_Offset;
break;
default:
DebugStr("\punknown powerbook type");
}
}
/*
* InitPrefs will load up the users selected system and HD sleep times from
* the preferences file. This is to avoid a problem with shutting down while
* attached to the mains.
*/
void InitPrefs() {
short vRefNum;
long dirID;
gSysSleep = 4*kUnitsOfSleep;
gHDSleep = 4*kUnitsOfSleep; // default in case this stuff breaks.
if (noErr == FindFolder(kOnSystemDisk,kPreferencesFolderType,true,&vRefNum,&dirID) ) {
FSSpec prefsFSSpec;
if ( noErr == FSMakeFSSpec( vRefNum, dirID, "\pRegulator Prefs",&prefsFSSpec) ) {
short refNum;
refNum = FSpOpenResFile( &prefsFSSpec, fsRdPerm);
if ( refNum != -1 ) {
Handle hndl;
UseResFile( refNum );
hndl = Get1IndResource('Pref',1);
if ( hndl ) {
short *ptr;
HLock(hndl);
ptr = *(short **)hndl;
gSysSleep = *ptr * kUnitsOfSleep;
ptr++;
gHDSleep = *ptr * kUnitsOfSleep;
if ( gSysSleep < gHDSleep )
gHDSleep = gSysSleep;
ReleaseResource( hndl );
}
FSClose ( refNum );
}
}
}
}